use std::path::Path;

use anyhow::Result;
use serde_derive::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config {
    pub proxy: String,
    pub operation: Operation,
    pub args: Args,
}


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Args {
    pub user: String,
    pub pass: String,
    pub url: String,
    pub query: String,
    pub dangerous: Vec<String>,
    pub file: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Operation {
    QUERY,
    DANGEROUS,
    UPLOAD,
}

impl AsRef<str> for Operation{
    fn as_ref(&self) -> &str {
        match &self {
            Operation::QUERY => "query",
            Operation::DANGEROUS => "dangerous",
            Operation::UPLOAD => "upload",
        }
    }
}

pub async fn init() -> Result<Config> {
    let cfg_name = "config.toml";
    init_config(cfg_name).await?;
    let res = async_fs::read_to_string(cfg_name).await?;
    Ok(toml::from_str::<Config>(&*res)?)
}

async fn init_config(cfg_name: &str) -> Result<()> {
    if Path::new(cfg_name).exists() {
        return Ok(());
    }

    let args = Args {
        user: "lcpt_zlc".into(),
        pass: "Zlc9636".into(),
        url: "30.2.18.2:1521/scfdb".into(),
        query: "select * from dual".into(),
        dangerous: vec!["".into(), "".into()],
        file: "temp.txt".into(),
    };

    let cfg = Config {
        proxy: "http://10.2.53.31:8888/fmsmng".into(),
        operation: Operation::UPLOAD,
        args,
    };

    Ok(async_fs::write(cfg_name, toml::to_string_pretty(&cfg)?).await?)
}
